home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / math / gle-3.000 / gle-3 / gle / d_ps.c < prev    next >
C/C++ Source or Header  |  1995-02-07  |  17KB  |  609 lines

  1. /*--------------------------------------------------------------*/
  2. /*    Post Script Driver, for GLE V3.0             */
  3. /*--------------------------------------------------------------*/
  4.  
  5. /*---------------------------------------------------------------------------*/
  6. #include "all.h"
  7.  
  8. #include <math.h>
  9. #include "core.h"
  10. #include "mygraph.h"
  11. #include "mydev.h"
  12. char *fontdir(char *s);
  13. extern int MAX_VECTOR; /* Cant send POSTSCRIPT too complex a path */
  14. static int ps_nvec;
  15.  
  16. extern int control_d;
  17. extern int dev_eps;
  18. extern struct gmodel g;
  19. /*---------------------------------------------------------------------------*/
  20. #define pi 3.141592653
  21. #define false 0
  22. #define true (!false)
  23. extern int BLACKANDWHITE;
  24. #define dbg if ((gle_debug & 64)>0)
  25. extern int gle_debug;
  26. char *font_getname(int i);
  27. void ddfill(void);
  28. void d_shade(void);
  29. void read_psfont(void);
  30. /*---------------------------------------------------------------------------*/
  31. /* The global variables that CORE keeps track of */
  32. /*-----------------------------------------------*/
  33.  
  34.     FILE *psfile;
  35.     int i,l,j;
  36.  
  37. colortyp g_cur_fill,g_cur_color;
  38.  
  39. /*---------------------------------------------------------------------------*/
  40. d_dfont(char *c)
  41. {
  42.     /* only used for the DFONT driver which builds fonts */
  43. }
  44. /*---------------------------------------------------------------------------*/
  45. d_tidyup()
  46. {}
  47. d_message(char *s)
  48. {
  49. #ifdef unix
  50.     printw("%s\n",s);
  51. #else
  52.     printf("%s\n",s);
  53. #endif
  54. }
  55. /*---------------------------------------------------------------------------*/
  56. d_devcmd(char *s)
  57. {
  58.     fprintf(psfile,"%s",s);
  59. }
  60. d_source(char *s)
  61. {
  62.     dbg fprintf(psfile,"%% SOURCE, %s",s);
  63. }
  64. /*---------------------------------------------------------------------------*/
  65. d_get_type(char *t)
  66. {
  67.     strcpy(t,"HARDCOPY, PS, FILLPATH");
  68.     if (dev_eps) strcat(t,", EPS,");
  69. }
  70. /*---------------------------------------------------------------------------*/
  71. d_set_path(int onoff)
  72. {
  73. }
  74. /*---------------------------------------------------------------------------*/
  75. d_newpath()
  76. {
  77.     fprintf(psfile," newpath ");
  78.     ps_nvec = 0;
  79. }
  80. /*---------------------------------------------------------------------------*/
  81. extern char output_file[];
  82. extern char input_file[];
  83. d_open(double width, double height)
  84. {
  85.     char *outfile;
  86.     char *s;
  87.     char outfileb[90] = "out.ps";
  88.  
  89.     outfile = &outfileb[0];
  90.     s = strrchr(input_file,'.');
  91.     if (s!=NULL) {
  92.         strcpy(outfile,input_file);
  93.         s = strrchr(outfile,'.');
  94.         if (dev_eps) strcpy(s,".eps");
  95.         else strcpy(s,".ps");
  96.     }
  97.     if (output_file[0]!=0) outfile = &output_file[0];
  98.     psfile = fopen(outfile,"w");
  99.     if (psfile == NULL) { perror("PS open file GLE_OUTPUT: ") ; exit(2); }
  100.  
  101. #ifdef __TURBOC__
  102.     printf("\n Writing output to file (%s) \n",outfile);
  103. #endif
  104.     if (!dev_eps) {
  105.         if (control_d) fprintf(psfile,"\x04 \n");
  106.         fprintf(psfile,"%%!PS-Adobe-1.0 \n");
  107.     } else {
  108.         fprintf(psfile,"%%!PS-Adobe-2.0 EPSF-2.0 \n");
  109.     }
  110.     fprintf(psfile,"%%%%BoundingBox: -1 -1 %g %g \n",floor(72*width/2.54+2),floor(72*height/2.54+2));
  111.     fprintf(psfile,"%%%%EndComments \n");
  112.     fprintf(psfile,"%%%%EndProlog \n");
  113.     fprintf(psfile,"gsave \n");
  114.     fprintf(psfile," \n");
  115.     fprintf(psfile,"/f {findfont exch scalefont setfont} bind def \n");
  116.     fprintf(psfile,"/s {show} bind def \n");
  117.     fprintf(psfile,"/ps {true charpath} bind def \n");
  118.     fprintf(psfile,"/l {lineto} bind def \n");
  119.     fprintf(psfile,"/m {newpath moveto} bind def \n");
  120.     fprintf(psfile,"matrix currentmatrix /originmat exch def \n");
  121.     fprintf(psfile,"/umatrix {originmat matrix concatmatrix setmatrix} def \n");
  122.     fprintf(psfile," \n");
  123. }
  124. /*---------------------------------------------------------------------------*/
  125. d_close()
  126. {
  127.     g_flush();
  128.     fprintf(psfile,"showpage \n");
  129.     fprintf(psfile,"grestore \n");
  130.     fprintf(psfile,"%%%%Trailer \n");
  131.     if (!dev_eps) if (control_d) fprintf(psfile,"\x04");
  132.     fclose(psfile);
  133. }
  134. /*---------------------------------------------------------------------------*/
  135. d_set_line_cap(int i)
  136. {
  137.     /*  lcap, 0= butt, 1=round, 2=projecting square */
  138.     if (!g.inpath) g_flush();
  139.     fprintf(psfile,"%d setlinecap \n",i);
  140. }
  141. /*---------------------------------------------------------------------------*/
  142. d_set_line_join(int i)
  143. {
  144.     if (!g.inpath) g_flush();
  145.     fprintf(psfile,"%d setlinejoin \n",i);
  146. }
  147. /*---------------------------------------------------------------------------*/
  148. d_set_line_miterlimit(double d)
  149. {
  150.     if (!g.inpath) g_flush();
  151.     fprintf(psfile,"%g setmiterlimit \n",d);
  152. }
  153. /*---------------------------------------------------------------------------*/
  154. d_set_line_width(double w)
  155. {
  156.     if (w==0) w = 0.02;
  157.     if (w<.0002) w = 0;
  158.     if (!g.inpath) g_flush();
  159.     fprintf(psfile,"%g setlinewidth \n",w);
  160. }
  161. /*---------------------------------------------------------------------------*/
  162. d_set_line_styled(double dd)
  163. {}
  164. d_set_line_style(char *s)
  165. {
  166.     /* should deal with [] for solid lines */
  167.     static char *defline[] = {"","","12","41","14","92","1282"
  168.     ,"9229","4114","54","73","7337","6261","2514"};
  169.     static char ob[200];
  170.     int l;
  171.  
  172.     if (!g.inpath) g_flush();
  173.     strcpy(ob,"[");
  174.     if (strlen(s)==1) s = defline[*s-'0'];
  175.     l = strlen(s);
  176.     for (i=0;i<l;i++)
  177.         sprintf(ob+strlen(ob),"%g ",(*(s+i)-'0')*g.lstyled);
  178.     strcat(ob,"]");
  179.     fprintf(psfile,"%s 0 setdash \n",ob);
  180. }
  181. /*---------------------------------------------------------------------------*/
  182. d_fill()
  183. {
  184.     fprintf(psfile,"gsave \n");
  185.     ddfill();
  186.     fprintf(psfile,"grestore \n");
  187. }
  188. void ddfill(void)
  189. {
  190.     if (g_cur_fill.b[B_F] == 255) return; /* clear fill, do nothing */
  191.     if (g_cur_fill.b[B_F] == 2) {d_shade(); return;}
  192.     set_fill();            /*because color and fill are the same*/
  193.     fprintf(psfile,"fill \n");
  194.     set_color();
  195. }
  196. void d_shade(void)
  197. {
  198.     double x,y,step1,step2;
  199.     fprintf(psfile,"gsave \n");
  200.     fprintf(psfile,"clip \n");
  201.     fprintf(psfile,"newpath  \n");
  202.     fprintf(psfile,"0 setgray \n");
  203.     step1 = g_cur_fill.b[B_B]/160.0;
  204.     step2 = g_cur_fill.b[B_G]/160.0;
  205.  
  206.     fprintf(psfile,"%g setlinewidth\n",(double) g_cur_fill.b[B_R]/160.0);
  207.     if (step1>0) {
  208.       fprintf(psfile,"%g %g %g { /x exch def \n",-40.0,step1,40.0);
  209.       fprintf(psfile,"x 0 moveto 40 x add 40 lineto stroke\n");
  210.       fprintf(psfile,"} for \n");
  211.     }
  212.     if (step2>0) {
  213.      fprintf(psfile,"%g %g %g { /x exch def \n",0.0,step2,80.0);
  214.      fprintf(psfile,"x 0 moveto -40 x add 40 lineto stroke\n");
  215.      fprintf(psfile,"} for \n");
  216.     }
  217.     fprintf(psfile,"grestore \n");
  218. /*    d_set_line_width(g.lwidth); */
  219. }
  220. /*---------------------------------------------------------------------------*/
  221. d_fill_ary(int nwk,double (*wkx)[],double (*wky)[])
  222. {
  223.     int i;
  224.     fprintf(psfile,"gsave \n");
  225.     fprintf(psfile,"newpath \n");
  226.     fprintf(psfile,"%g %g moveto \n",(*wkx)[0],(*wky)[0]);
  227.     for (i=1;i<nwk;i++)
  228.         fprintf(psfile,"%g %g l \n",(*wkx)[i],(*wky)[i]);
  229.     set_fill();
  230.     fprintf(psfile,"fill \n");
  231.     set_color();
  232.     fprintf(psfile,"grestore \n");
  233. }
  234. d_line_ary(int nwk,double (*wkx)[],double (*wky)[])
  235. {
  236.     int i;
  237.     fprintf(psfile,"gsave \n");
  238.     fprintf(psfile,"newpath \n");
  239.     fprintf(psfile,"%g %g moveto \n",(*wkx)[0],(*wky)[0]);
  240.     for (i=1;i<nwk;i++)
  241.         fprintf(psfile,"%g %g l \n",(*wkx)[i],(*wky)[i]);
  242.     fprintf(psfile,"stroke \n");
  243.     fprintf(psfile,"grestore \n");
  244. }
  245. /*---------------------------------------------------------------------------*/
  246. d_stroke()
  247. {
  248.     fprintf(psfile,"gsave \n");
  249.     fprintf(psfile,"stroke \n");
  250.     fprintf(psfile,"grestore \n");
  251. }
  252. /*---------------------------------------------------------------------------*/
  253. d_clip()
  254. {
  255.     fprintf(psfile,"clip \n");
  256. }
  257. /*---------------------------------------------------------------------------*/
  258. d_set_matrix(double newmat[3][3])
  259. {
  260.     fprintf(psfile," [%g %g %g %g %g %g] umatrix \n ",
  261.         newmat[0][0],newmat[1][0],newmat[0][1],
  262.         newmat[1][1],newmat[0][2],newmat[1][2]);
  263. }
  264. /*---------------------------------------------------------------------------*/
  265. d_move(double zx,double zy)
  266. {
  267.     if (g.inpath==true)
  268.         fprintf(psfile,"%g %g moveto \n",zx,zy);
  269.     else {
  270.         ps_nvec++;
  271.         fprintf(psfile,"%g %g m \n",zx,zy);
  272.     }
  273. }
  274. /*---------------------------------------------------------------------------*/
  275. d_reverse()     /* reverse the order of stuff in the current path */
  276. {
  277.     fprintf(psfile,"reversepath \n");
  278. }
  279. /*---------------------------------------------------------------------------*/
  280. d_closepath()
  281. {
  282.     fprintf(psfile,"closepath \n");
  283. }
  284. /*---------------------------------------------------------------------------*/
  285. d_line(double zx,double zy)
  286. {
  287.     dbg gprint("in d_line  g.curx,y  %g %g ",g.curx,g.cury);
  288.     if (g.xinline==false) {
  289.         d_move(g.curx,g.cury);
  290.     }
  291.     ps_nvec++;
  292.     if (ps_nvec>MAX_VECTOR) {
  293.         gprint("Warning, complex path, if filling fails then try /nomaxpath \n");
  294.         ps_nvec = 0; g_flush(); d_move(g.curx,g.cury);
  295.     }
  296.     if (fprintf(psfile,"%g %g l \n",zx,zy)==EOF) {
  297.         perror("=========Unable to write to output file ");
  298.     }
  299. }
  300. /*---------------------------------------------------------------------------*/
  301. d_clear()
  302. {
  303.     int flipit;
  304.     g_scale(72.0,72.0);
  305.     g_scale(.393701,.393701);
  306.     if (!dev_eps) g_translate(1.5,1.01);
  307.     if ((!dev_eps) && (g.userwidth>g.userheight)) {
  308.         fprintf(psfile,"%% Flipping coord system \n");
  309.         g_move(0.0,0.0);
  310.         g_rotate(90.0);
  311.         g_translate(0.0,-g.userheight);
  312.         g_move(0.0,0.0);
  313.     }
  314. }
  315. /*---------------------------------------------------------------------------*/
  316. d_flush()
  317. {
  318.     if (g.inpath) return;
  319.     if (g.xinline) {
  320.         fprintf(psfile,"stroke \n");
  321.         ps_nvec = 0;
  322.     }
  323. }
  324. /*---------------------------------------------------------------------------*/
  325. d_arcto(dbl x1,dbl y1,dbl x2,dbl y2,dbl rrr)
  326. {
  327.     if (g.xinline==false)  d_move(g.curx,g.cury);
  328.     fprintf(psfile,"%g %g %g %g %g arcto clear %g %g l \n",x1,y1,x2,y2,rrr,x2,y2);
  329.     g.xinline = true;
  330. }
  331. /*---------------------------------------------------------------------------*/
  332. d_arc(dbl r,dbl t1,dbl t2,dbl cx,dbl cy)
  333. {
  334.     double dx,dy;
  335.     double x,y;
  336.     g_get_xy(&x,&y);
  337.     polar_xy(r,t1,&dx,&dy);
  338.     if (!g.inpath) g_move(cx+dx,cy+dy);
  339.     fprintf(psfile,"%g %g %g %g %g arc \n",cx,cy,r,t1,t2);
  340.     g.xinline = true;
  341.     if (!g.inpath) g_move(x,y);
  342. }
  343. /*---------------------------------------------------------------------------*/
  344. d_narc(dbl r,dbl t1,dbl t2,dbl cx,dbl cy)
  345. {
  346.     double dx,dy;
  347.     double x,y;
  348.     g_get_xy(&x,&y);
  349.     polar_xy(r,t1,&dx,&dy);
  350.     if (!g.inpath) g_move(cx+dx,cy+dy);
  351.     fprintf(psfile,"%g %g %g %g %g arcn \n",cx,cy,r,t1,t2);
  352.     g.xinline = true;
  353.     if (!g.inpath) g_move(x,y);
  354. }
  355. /*---------------------------------------------------------------------------*/
  356. d_box_fill(dbl x1, dbl y1, dbl x2, dbl y2)
  357. {
  358.     if (g.inpath==true) xdbox(x1,y1,x2,y2);
  359.     else {
  360.         g_flush();
  361.         fprintf(psfile," newpath ");
  362.         xdbox(x1,y1,x2,y2);
  363.         ddfill();
  364.         fprintf(psfile,"newpath \n");
  365. /*        set_fill();
  366.         fprintf(psfile,"fill \n");
  367.         set_color();
  368. */
  369.     }
  370. }
  371. d_box_stroke(dbl x1, dbl y1, dbl x2, dbl y2)
  372. {
  373.     if (g.inpath==true) xdbox(x1,y1,x2,y2);
  374.     else {
  375.         g_flush();
  376.         fprintf(psfile," newpath ");
  377.         xdbox(x1,y1,x2,y2);
  378.         fprintf(psfile,"stroke \n");
  379.         ps_nvec = 0;
  380.     }
  381. }
  382. /*---------------------------------------------------------------------------*/
  383. xdbox(double x1, double y1, double x2, double y2)
  384. {
  385.    fprintf(psfile," %g %g moveto %g %g l %g %g l %g %g l closepath \n"
  386.             ,x1,y1,x2,y1,x2,y2,x1,y2);
  387. }
  388. /*---------------------------------------------------------------------------*/
  389. d_circle_stroke(double zr)
  390. {
  391.     double x,y;
  392.     g_get_xy(&x,&y);
  393.     if (g.inpath==true)
  394.         fprintf(psfile," %g %g %g 0 360 arc \n",x,y,zr);
  395.     else {
  396.         g_flush();
  397.         fprintf(psfile," newpath ");
  398.         fprintf(psfile," %g %g %g 0 360 arc \n",x,y,zr);
  399.         fprintf(psfile,"stroke \n");
  400.     }
  401. }
  402. d_circle_fill(double zr)
  403. {
  404.     double x=g.curx,y=g.cury;
  405.     if (g.inpath==true)
  406.         fprintf(psfile," %g %g %g 0 360 arc \n",x,y,zr);
  407.     else {
  408.         g_flush();
  409.         fprintf(psfile,"newpath ");
  410.         fprintf(psfile,"%g %g %g 0 360 arc \n",x,y,zr);
  411.         ddfill();
  412.         fprintf(psfile,"newpath \n");
  413. /*
  414.  
  415.         set_fill();
  416.         fprintf(psfile,"fill \n");
  417.         set_color();
  418. */
  419.     }
  420. }
  421. /*---------------------------------------------------------------------------*/
  422. d_bezier(dbl x1,dbl y1,dbl x2,dbl y2,dbl x3,dbl y3)
  423. {
  424.     double x=g.curx,y=g.cury;
  425.     if (g.inpath==true) {
  426.         if (g.xinline==false)  d_move(g.curx,g.cury);
  427.         fprintf(psfile,"%g %g %g %g %g %g curveto \n"
  428.             ,x1,y1,x2,y2,x3,y3);
  429.     } else {
  430.         g_flush();
  431.         if (!g.xinline) fprintf(psfile,"%g %g moveto ",x,y);
  432.         fprintf(psfile,"%g %g %g %g %g %g curveto \n"
  433.             ,x1,y1,x2,y2,x3,y3);
  434.     }
  435.     g.xinline = true;
  436. }
  437. /*---------------------------------------------------------------------------*/
  438. /*---------------------------------------------------------------------------*/
  439. test_psfile()
  440. {
  441.     if (psfile==NULL) return;
  442.     set_color();
  443. }
  444. set_color()
  445. {
  446.     if (BLACKANDWHITE) {
  447.          fprintf(psfile,"%g setgray \n",((g_cur_color.b[B_R]*3.0/255.0
  448.         +g_cur_color.b[B_G]*2.0/255.0+g_cur_color.b[B_B]/255.0) / 6));
  449.     } else
  450.          fprintf(psfile,"%g %g %g setrgbcolor \n",g_cur_color.b[B_R]/255.0
  451.         ,g_cur_color.b[B_G]/255.0,g_cur_color.b[B_B]/255.0);
  452. }
  453. set_fill()
  454. {
  455.     if (BLACKANDWHITE) {
  456.          fprintf(psfile,"%g setgray \n",((g_cur_fill.b[B_R]*3.0/255.0
  457.         +g_cur_fill.b[B_G]*2.0/255.0+g_cur_fill.b[B_B]/255.0) / 6));
  458.     } else
  459.          fprintf(psfile,"%g %g %g setrgbcolor \n",g_cur_fill.b[B_R]/255.0
  460.         ,g_cur_fill.b[B_G]/255.0,g_cur_fill.b[B_B]/255.0);
  461. }
  462. /*---------------------------------------------------------------------------*/
  463. d_set_color(int32 f)
  464. {
  465.     g_flush();
  466.     g_cur_color.l = f;
  467.     set_color();
  468. }
  469. d_set_fill(int32 f)
  470. {
  471.     g_cur_fill.l = f;
  472. }
  473. /*---------------------------------------------------------------------------*/
  474. d_beginclip()
  475. {
  476.     fprintf(psfile,"gsave \n");
  477. }
  478. d_endclip()
  479. {
  480.     char *state;
  481.     g_flush();
  482.     fprintf(psfile,"grestore \n");
  483.     state = myallocz(300);
  484.     g_get_state(state);
  485.     g_set_state(state);
  486.     myfree(state);
  487. }
  488. /*---------------------------------------------------------------------------*/
  489. struct psfont_struct {char *sname; char *lname;} ;
  490. struct psfont_struct psf[70] = { /* leaves room for twenty more from PSFONT.DAT*/
  491.     "PSTR",        "Times-Roman",
  492.     "PSTI",        "Times-Italic",
  493.     "PSTB",        "Times-Bold",
  494.     "PSTBI",    "Times-BoldItalic",
  495.     "RM",        "Times-Roman",
  496.     "RMI",        "Times-Italic",
  497.     "RMB",        "Times-Bold",
  498.     "RMBI",        "Times-BoldItalic",
  499.     "SS",        "Helvetica",
  500.     "SSB",        "Helvetica-Bold",
  501.     "SSI",        "Helvetica-Oblique",
  502.     "SSBI",        "Helvetica-BoldOblique",
  503.     "PSH",        "Helvetica",
  504.     "PSHB",        "Helvetica-Bold",
  505.     "PSHBO",    "Helvetica-BoldOblique",
  506.     "PSHO",        "Helvetica-Oblique",
  507.     "PSAGB",    "AvantGarde-Book",
  508.     "PSAGBO",    "AvantGarde-BookOblique",
  509.     "PSAGD",    "AvantGarde-Demi",
  510.     "PSAGDO",    "AvantGarde-DemiOblique",
  511.     "PSBD",        "Bookman-Demi",
  512.     "PSBDI",    "Bookman-DemiItalic",
  513.     "PSBL",        "Bookman-Light",
  514.     "PSBLI",    "Bookman-LightItalic",
  515.     "PSC",        "Courier",
  516.     "PSCB",        "Courier-Bold",
  517.     "PSCBO",    "Courier-BoldOblique",
  518.     "PSCO",        "Courier-Oblique",
  519.     "TT",        "Courier",
  520.     "TTB",        "Courier-Bold",
  521.     "TTBI",        "Courier-BoldOblique",
  522.     "TTI",        "Courier-Oblique",
  523.     "PSNCSB",    "NewCenturySchlbk-Bold",
  524.     "PSNCSBI",    "NewCenturySchlbk-BoldItalic",
  525.     "PSNCSI",    "NewCenturySchlbk-Italic",
  526.     "PSNCSR",    "NewCenturySchlbk-Roman",
  527.     "PSPB",        "Palatino-Bold",
  528.     "PSPBI",    "Palatino-BoldItalic",
  529.     "PSPI",        "Palatino-Italic",
  530.     "PSPR",        "Palatino-Roman",
  531.     "PSZCMI",    "ZapfChancery-MediumItalic",
  532.     "PSZD",        "ZapfDingbats",
  533.     "PSSYM",    "Symbol",
  534.     NULL,NULL
  535. };
  536. /*---------------------------------------------------------------------------*/
  537. d_char(int font, int cc)
  538. {
  539.     double x,y;
  540.     char *s;
  541.     static int this_font;
  542.     static double this_size;
  543.  
  544.  
  545.     read_psfont();
  546.     if (font_get_encoding(font)>2) {
  547.         my_char(font,cc);
  548.         return;
  549.     }
  550.     if (this_font!=font || this_size!=g.fontsz) {
  551.         if (g.fontsz<0.00001) {
  552.             gprint("Font size is zero, error ********* \n");
  553.             return;
  554.         }
  555.         s = font_getname(font);
  556.         for (i=0;;i++) {
  557.             if (psf[i].sname==NULL) break;
  558.             dbg printf("font match  {%s} {%s} \n",s,psf[i].sname);
  559.             if (strcmp(psf[i].sname,s)==0) break;
  560.         }
  561.         if (psf[i].sname==NULL) {
  562.             my_char(font,cc);
  563.             return;
  564.         }
  565.         this_font = font;
  566.         this_size = g.fontsz;
  567.         fprintf(psfile," %f /%s f ",g.fontsz,psf[i].lname);
  568.     }
  569.     if (g.inpath==true) {
  570.         if (isalnum(cc) && cc<127) fprintf(psfile,"(%c) ps ",cc);
  571.         else  fprintf(psfile,"(\\%o) ps ",cc);
  572.     } else {
  573.         if (isalnum(cc) && cc<127) fprintf(psfile,"(%c) s ",cc);
  574.         else  fprintf(psfile,"(\\%o) s ",cc);
  575.     }
  576. }
  577. char *fontdir(char *s);
  578. void read_psfont(void)  /* add aditional ps fonts,  e.g.  pstr = TimesRoman */
  579. {
  580.     static init_done;
  581.     FILE *fptr;
  582.     char fname[80],*s;
  583.     char inbuff[90];
  584.     if (init_done) return;
  585.     init_done = true;
  586.  
  587.     /* Find last used psf */
  588.     for (i=0;;i++) if (psf[i].sname==NULL) break;
  589.  
  590.     strcpy(fname,fontdir("psfont.dat"));
  591.     fptr = fopen(fname,"r");
  592.     if (fptr==0) return; /* if not exists then don't bother */
  593.  
  594.     for (fgets(inbuff,200,fptr);!feof(fptr);fgets(inbuff,200,fptr)) {
  595.         s = strchr(inbuff,'!');
  596.         if (s!=NULL) *s=0;
  597.         s = strtok(inbuff," \t,\n");
  598.         if (s!=NULL) if (*s!='\n') {
  599.             psf[i].sname = sdup(s);
  600.             s = strtok(0," \t,\n");
  601.             psf[i].lname = sdup(s);
  602.             i++;
  603.         }
  604.     }
  605.     psf[i].sname = NULL;
  606.     psf[i].lname = NULL;
  607. }
  608.  
  609.